package com.lmabbe.common.mvc.core.controller;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.lmabbe.common.global.query.GeneralQuery;
import com.lmabbe.common.global.result.R;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @author lmabbe
 * @data 2021/3/28 20:13
 */
public abstract class BaseController<S extends IService<T>, T> {

    private S baseService;

    /**
     * 初始化baseService
     * 由于dubbo的@DubboReference在基类初始化不生效所以由子类注入
     *
     * @date 2021/9/13 9:49 上午
     * @author liming
     */
    @PostConstruct
    protected abstract void initBaseService();


    @Operation(summary = "获取所有")
    @GetMapping("all")
    public R list() {
        List<T> list = this.getBaseService().list();
        return R.success(list);
    }

    @Operation(summary = "分页获取")
    @GetMapping("page")
    public R list(GeneralQuery query) {
        Page<T> tPage = new Page<>(query.getPageNo(), query.getPageSize());
        IPage<T> page = this.getBaseService().page(tPage);
        return R.page(page);
    }

    @Operation(summary = "获取单个实体类")
    @GetMapping("/{id}")
    public R getById(@PathVariable String id) {
        T byId = this.getBaseService().getById(id);
        return R.success(byId);
    }

    @Operation(summary = "新增单个实体类")
    @PostMapping()
    public R add(@RequestBody T entity) {
        R beforeUpdate = beforeInsert(entity);
        if (beforeUpdate.getCode() == 200) {
            this.getBaseService().save(entity);
            afterInsert(entity);
            return R.success();
        } else {
            return beforeUpdate;
        }
    }

    @Operation(summary = "修改单个实体类")
    @PutMapping()
    public R update(@RequestBody T entity) {
        boolean beforeUpdate = beforeUpdate(entity);
        if (beforeUpdate) {
            this.getBaseService().updateById(entity);
            afterUpdate(entity);
        }
        return R.success();
    }

    @Operation(summary = "删除")
    @DeleteMapping("/{id}")
    public R delete(@PathVariable Long id) {
        boolean beforeUpdate = beforeDelete(id);
        if (beforeUpdate) {
            this.getBaseService().removeById(id);
            afterDelete(id);
        }
        return R.success();
    }


    /**
     * 更新前操作
     */
    protected boolean beforeUpdate(T entity) {
        return true;
    }

    /**
     * 更新后操作
     */
    protected void afterUpdate(T entity) {
    }

    /**
     * 新增钱操作
     */
    protected R beforeInsert(T entity) {
        return R.success();
    }

    /**
     * 新增后操作
     */
    protected void afterInsert(T entity) {
    }

    /**
     * 删除前操作
     */
    protected boolean beforeDelete(Long id) {
        return true;
    }

    /**
     * 删除后操作
     */
    protected void afterDelete(Long id) {
    }

    public S getBaseService() {
        return baseService;
    }

    public void setBaseService(S baseService) {
        this.baseService = baseService;
    }
}
